package com.heiye.auth.service.Impl;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Preconditions;
import com.heiye.auth.constant.RedisKeyConstants;
import com.heiye.auth.enums.LoginTypeEnum;
import com.heiye.auth.enums.ResponseCodeEnum;
import com.heiye.auth.factory.LoginStrategyFactory;
import com.heiye.auth.model.dto.user.UserLoginRspDTO;
import com.heiye.auth.rpc.UserRpcService;
import com.heiye.auth.service.UserService;
import com.heiye.auth.model.vo.user.UserLoginReqVO;
import com.heiye.auth.strategy.LoginStrategy;
import com.heiye.framework.common.exception.BizException;
import com.heiye.framework.common.response.Response;
import com.heiye.user.api.dto.resp.RegisterUserRspDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.heiye.framework.biz.context.thread.LoginUserContextHolder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author: heiye
 * @date: 2024/09/23 下午3:31
 * @version: v1.0.0
 * @description: 用户校验ServiceImpl
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private LoginStrategyFactory loginStrategyFactory;

    /**
     * 登录校验
     *
     * @param userLoginReqVO
     * @return
     */
    @Override
    public Response<UserLoginRspDTO> loginAndRegister(UserLoginReqVO userLoginReqVO) {
        // 获取登录类型
        Integer type = userLoginReqVO.getType();

        LoginTypeEnum loginTypeEnum = LoginTypeEnum.valueOf(type);

        // 判断登录类型
        if (Objects.isNull(loginTypeEnum)) {
            throw new BizException(ResponseCodeEnum.LOGIN_TYPE_ERROR);
        }

        // 获取登录策略
        LoginStrategy loginStrategy = loginStrategyFactory.getLoginStrategy(loginTypeEnum);

        // 登录
        RegisterUserRspDTO registerUserRspDTO = loginStrategy.login(
                userLoginReqVO.getIdentifier(),
                userLoginReqVO.getCredential(),
                userLoginReqVO.getType());

        // SaToken 登录用户, 入参为用户 ID
        StpUtil.login(registerUserRspDTO.getId());

        // 获取 Token 令牌
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        // 返回参数
        UserLoginRspDTO userLoginRspDTO = UserLoginRspDTO.builder()
                .token(tokenInfo.tokenValue)
                .isRegister(registerUserRspDTO.getIsRegister())
                .build();

        return Response.success(userLoginRspDTO);
    }

    /**
     * 用户登出
     *
     * @return
     */
    @Override
    public Response<?> logout() {
        // 从线程中获取userId
        Long userId = LoginUserContextHolder.getUserId();

        // 退出登录
        StpUtil.logout(userId);
        return Response.success();
    }
}
